import toolFun from "@/tool/tool-fun";

let serialStatus = "serial" in navigator;
let serialPort, inter, reader;

async function openSelectSerial() {
  // 提示用户选择一个串口。 - 过滤arduino uno usb 供应商/产品id
  serialPort = await navigator.serial.requestPort([
    { usbVendorId: 0x2341, usbProductId: 0x0043 },
    { usbVendorId: 0x2341, usbProductId: 0x0001 },
  ]);
  return serialPort;
}

async function openSerial(callback, baudRate = 9600) {
  // 清理历史打开穿行流
  await closeSerial();

  // 等待串口打开
  await serialPort.open({ baudRate });

  console.log("LJ - 串口已打开...");

  if (!serialPort.readable) {
    return;
  }

  reader = serialPort.readable.getReader();

  // 监听来自串行设备的数据
  inter = setInterval(async () => {
    try {
      const { value, done } = await reader.read();
      if (done) {
        return;
      }
      // value 是一个 Uint8Array
      callback(value);
    } catch (e) {
      // closeSerial();
    }
  }, 1000);

  return true;
}

async function sendData(bytes) {
  const writer = serialPort.writable.getWriter();
  try {
    await writer.write(bytes);
  } catch (e) {
    console.error(e);
  } finally {
    // 允许稍后关闭串口。
    writer.releaseLock();
  }
}

async function closeSerial() {
  if (!inter) {
    return;
  }
  clearInterval(inter);
  inter = undefined;
  console.log(serialPort);
  if (serialPort && serialPort.readable) {
    // 关闭读取器
    if (reader) {
      await reader.releaseLock();
      reader = undefined;
    }

    await serialPort.close();
  }
}

export default {
  serialStatus,
  openSelectSerial,
  openSerial,
  sendData,
  syncSendData: toolFun.lock(sendData),
  closeSerial,
};
